package com.zf.yichat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.zf.yichat.dto.GroupUserDto;
import com.zf.yichat.im.mapper.RcGroupMembersMapper;
import com.zf.yichat.im.mapper.RcGroupsMapper;
import com.zf.yichat.mapper.GroupAdminMapper;
import com.zf.yichat.mapper.GroupManageMapper;
import com.zf.yichat.mapper.GroupSilentMapper;
import com.zf.yichat.model.*;
import com.zf.yichat.service.GroupService;
import com.zf.yichat.service.UserService;
import com.zf.yichat.service.config.RongCloudApplication;
import com.zf.yichat.utils.common.DtoChangeUtils;
import com.zf.yichat.utils.common.N3d;
import com.zf.yichat.utils.response.FsPage;
import com.zf.yichat.utils.response.FsResponse;
import com.zf.yichat.vo.GroupRoleType;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 一句话描述功能
 *
 * @author fengsong
 * @date create in 10:21 2019/6/18 2019
 */
@Service
public class GroupServiceImpl implements GroupService {



    @Autowired
    private UserService userService;


    @Autowired
    private RcGroupsMapper rcGroupsMapper;

    @Autowired
    private RcGroupMembersMapper rcGroupMembersMapper;

    @Autowired
    private GroupAdminMapper groupAdminMapper;

    @Autowired
    private GroupSilentMapper groupSilentMapper;

    @Autowired
    private GroupManageMapper groupManageMapper;

    // 注入配置文件中的融云API配置
    @Value("${rongcloud.key}")
    private String appKey;

    @Value("${rongcloud.secret}")
    private String appSecret;

    @Autowired
    private RongCloudApplication rongCloudApplication;


    @Override
    public FsResponse selectUserList(FsPage page, Long userId, Integer groupId) {


   /*     Example select = new Example(RcGroupMembers.class);
        select.createCriteria().andEqualTo("groupid", groupId);*/

//        if (page.getPageNo() != -1) {
//            PageHelper.startPage(page.getPageNo(), page.getPageSize());
//        }

        //暂时限制返回1000个群用户  10.23日已取消
        List<RcGroupMembers> list = rcGroupMembersMapper.selectList(groupId);
        PageInfo<RcGroupMembers> pageInfo = new PageInfo<>(list);
        FsResponse res = DtoChangeUtils.getPageList(userService.selectList(pageInfo.getList().stream().map(v -> v.getMemberid().longValue()).collect(Collectors.toList())), c -> {

            GroupUserDto dto = new GroupUserDto();
            dto.setAvatar(c.getAvatar());
            dto.setNick(c.getNick());
            dto.setUserId(c.getId());
            return dto;

        });

        res.setCount(pageInfo.getTotal());
        //第一页处理 管理员在第一个
        if (page.getPageNo() == 1 && res.getCount() > 0) {
            List<GroupUserDto> dtos = (List<GroupUserDto>) res.getData();
            //排序
            Long first = list.get(0).getMemberid().longValue();
            GroupUserDto firstD = null;
            List<GroupUserDto> news = new ArrayList<>();
            news.add(new GroupUserDto());
            for (GroupUserDto d : dtos) {
                if (d.getUserId().compareTo(first)==0) {
                    firstD = d;
                } else {
                    news.add(d);
                }
            }

            if (firstD != null) {
                news.set(0, firstD);
            }

            res.setData(news);
        }


        return res;
    }




    @Override
    public void updateRoleType(Long userId, Integer groupId, GroupRoleType roleType, Integer status) {

        GroupAdmin admin = selectAdmin(userId, groupId);

        //取消设置管理员
        if (Objects.nonNull(admin)) {
            admin.setStatus(status == 0 ? 1 : 0);
            admin.setUtime(new Date());
            groupAdminMapper.updateByPrimaryKeySelective(admin);
        } else {
            admin = new GroupAdmin();
            admin.setGroupId(groupId);
            admin.setUserId(userId);
            admin.setStatus(status == 0 ? 1 : 0);
            groupAdminMapper.insertSelective(admin);
        }

    }

    @Override
    public List<GroupUserDto> selectAdminList(Integer groupId) {
        Example example = new Example(GroupAdmin.class);
        example.createCriteria().andEqualTo("groupid", groupId).andEqualTo("status", 0);
        return DtoChangeUtils.getList(groupAdminMapper.selectByExample(example), v -> {
            GroupUserDto dto = new GroupUserDto();

            User user = userService.selectById(v.getUserId());
            dto.setAvatar(user.getAvatar());
            dto.setNick(user.getNick());
            dto.setUserId(v.getUserId());
            return dto;
        });
    }

    @Override
    public List<GroupUserDto> selectSilentList(Integer groupId) {
        Example example = new Example(GroupSilent.class);
        example.createCriteria().andEqualTo("groupid", groupId).andEqualTo("status", 1).andEqualTo("type", 0);
        return DtoChangeUtils.getList(groupSilentMapper.selectByExample(example), v -> {
            GroupUserDto dto = new GroupUserDto();
            User user = userService.selectById(v.getUserId());
            dto.setAvatar(user.getAvatar());
            dto.setNick(user.getNick());
            dto.setUserId(v.getUserId());
            return dto;
        });
    }

    @Override
    public GroupAdmin selectAdmin(Long userId, Integer groupId) {
        Example example = new Example(GroupAdmin.class);
        example.createCriteria().andEqualTo("userId", userId).andEqualTo("groupid", groupId);
        return groupAdminMapper.selectOneByExample(example);
    }

    @Override
    public void updateSilentStatus(Long userId, Integer groupId, Integer silentType, Integer status) {

        Example example = new Example(GroupSilent.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("groupid", groupId).andEqualTo("type", silentType);

        //如果是群成员禁言
        if (Objects.nonNull(silentType) && silentType == 0) {
            criteria.andEqualTo("userId", userId);
        }

        GroupSilent silent = groupSilentMapper.selectOneByExample(example);

        if (Objects.nonNull(silent)) {
            silent.setStatus(status);
            silent.setUtime(new Date());
            groupSilentMapper.updateByPrimaryKeySelective(silent);

        } else {
            silent = new GroupSilent();
            silent.setGroupId(groupId);
            silent.setStatus(1);
            silent.setUserId(userId);
            silent.setType(silentType);
            groupSilentMapper.insertSelective(silent);
        }

    }

    @Override
    public boolean isAdmin(Integer groupId, Long userId) {
        GroupAdmin admin = selectAdmin(userId, groupId);
        return Objects.nonNull(admin) && admin.getStatus() == 0;
    }

    @Override
    public Long getCreator(Integer groupId) {
        return selectById(groupId).getCreatorid().longValue();
    }

    @Override
    public RcGroups selectById(Integer id) {
        return rcGroupsMapper.selectByPrimaryKey(id);
    }

    @Override
    public GroupRoleType selectRoleType(Integer groupId, Long userId) {
        return isAdmin(groupId, userId) ? GroupRoleType.amdin : (getCreator(groupId).compareTo(userId) == 0 ? GroupRoleType.creator : GroupRoleType.common);
    }


    @Override
    public List<RcGroupMembers> selectGroupByUserId(Long userId) {
        Example example = new Example(RcGroupMembers.class);
        example.createCriteria().andEqualTo("memberid", userId);
        return rcGroupMembersMapper.selectByExample(example);
    }

    @Override
    public RcGroupMembers selectGroupMember(Integer groupId, Long userId) {
        Example example = new Example(RcGroupMembers.class);
        example.createCriteria().andEqualTo("groupid", groupId).andEqualTo("memberid", userId);
        return rcGroupMembersMapper.selectOneByExample(example);
    }

    @Override
    public Integer countMember(Integer groupId) {
        Example example = new Example(RcGroupMembers.class);
        example.createCriteria().andEqualTo("groupid", groupId);
        return rcGroupMembersMapper.selectCountByExample(example);
    }

    @Override
    public Integer getGroupSilentStatus(Integer groupId) {

        Example example = new Example(GroupSilent.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("groupid", groupId).andEqualTo("type", 1);

        GroupSilent silent = groupSilentMapper.selectOneByExample(example);

        return Optional.ofNullable(silent).map(GroupSilent::getStatus).orElse(0);


    }

    @Override
    public List<RcGroupMembers> selectGroupByIds(List<Integer> groupId, Long userId) {
        Example example = new Example(RcGroupMembers.class);
        example.createCriteria().andEqualTo("memberid", userId).andIn("groupid", groupId);
        return rcGroupMembersMapper.selectByExample(example);
    }


    @Override
    public List<RcGroups> selectMyGroupList(Long userId) {

        return rcGroupsMapper.selectList(userId.intValue());
    }

    @Override
    public List<RcGroups> selectMyOwnerList(Long userId) {

        return rcGroupsMapper.selectOwnerList(userId.intValue());
    }

    @Override
    public List<RcGroups> selectGroupListByCreater(Long userId) {
        Example example = new Example(RcGroups.class);
        example.createCriteria().andEqualTo("creatorid", userId);
        return rcGroupsMapper.selectByExample(example);
    }

    @Override
    public int selectProtectStatus(Integer groupId) {

        Example example = new Example(GroupSilent.class);
        Example.Criteria criteria = example.createCriteria();
        //状态为群保护状态设置
        criteria.andEqualTo("groupid", groupId).andEqualTo("type", 2);
        GroupSilent silent = groupSilentMapper.selectOneByExample(example);
        return Optional.ofNullable(silent).map(GroupSilent::getStatus).orElse(0);
    }

    @Override
    public void setProtectStatus(Long userId, Integer groupId, Integer status) {
        Example example = new Example(GroupSilent.class);
        Example.Criteria criteria = example.createCriteria();
        //状态为群保护状态设置
        criteria.andEqualTo("groupid", groupId).andEqualTo("type", 2);
        GroupSilent silent = groupSilentMapper.selectOneByExample(example);
        if (Objects.nonNull(silent)) {
            silent.setStatus(status);
            silent.setUserId(userId);
            groupSilentMapper.updateByPrimaryKeySelective(silent);
        } else {
            silent = new GroupSilent();
            silent.setStatus(status);
            silent.setUserId(userId);
            silent.setGroupId(groupId);
            silent.setType(2);
            groupSilentMapper.insertSelective(silent);
        }
    }

    @Override
    public RcGroups selectGroupsById(Long decodeGroupId) {
        return rcGroupsMapper.selectGroupById(decodeGroupId);
    }

    @Override
    public GroupAdmin selectAdminByGroupId(Long decodeGroupId) {
        return groupAdminMapper.selectAdminByGroupId(decodeGroupId);
    }

    @Override
    public Integer checkMemberInGroup(Integer groupId, Long userId) {
        return rcGroupMembersMapper.checkMemberInGroup(groupId, userId);
    }

    @Override
    public void memberQuit(Long uid, Integer gid) throws Exception{

        // 融云退出群组
        HttpPost httpPost = rongCloudApplication.imConstructor("group/quit");
        // 设置请求消息体参数
        String encodeGroupId = N3d.encode(Long.valueOf(gid));
        String encodeUserId = N3d.encode(Long.valueOf(uid));

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("userId", encodeUserId));
        params.add(new BasicNameValuePair("groupId", encodeGroupId));

        httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
        String response = rongCloudApplication.executeReq(httpPost);
        // 解析响应数据
        JSONObject jsonObject = JSON.parseObject(response);
        String whitelistCode = jsonObject.getString("code");
        if ("200".equals(whitelistCode)) {
            // 更新群组用户的状态
            rcGroupMembersMapper.memberQuit(uid, gid);
        }


    }

    @Override
    public List<GroupManage> queryAssociationList() {
        return groupManageMapper.selectAll();
    }
}
